package br.com.damazzy.negocio.persistencia.dao;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import br.com.damazzy.conexao.Conexao;
import br.com.damazzy.negocio.entidade.Pessoa;
import br.com.damazzy.negocio.entidade.Receita;
import br.com.damazzy.negocio.entidade.TipoPagamento;
import br.com.damazzy.negocio.entidade.Venda;

import com.ibm.icu.text.SimpleDateFormat;

public class ReceitaDaoImpl implements ReceitaDao {

	public Receita alterar(Receita objeto) throws Exception {
		
		Connection conn = null;
		PreparedStatement ps = null;
		int cont = 1;
		
		try {
			conn = Conexao.criarConexao();
			
			StringBuffer sql = new StringBuffer();
			sql.append("update damazzy.receita set receitarecebida = ?, valorpago = ?, datarecebimento = ? where idreceita = ?");
			
			ps = conn.prepareStatement(sql.toString());
			ps.setInt(cont++, objeto.getReceitaRecebida());
			ps.setBigDecimal(cont++, objeto.getValorPago());
			ps.setDate(cont++, new java.sql.Date(objeto.getDataRecebimento().getTime()));
			ps.setLong(cont++, objeto.getIdReceita());
			
			ps.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao alterar a receita.");
		} finally {
			Conexao.fecharConexao(conn);
		}
		
		return null;
	}
	
	public void inativar(Receita objeto) throws Exception {
		
		Connection conn = null;
		PreparedStatement ps = null;
		int cont = 1;
		
		try {
			conn = Conexao.criarConexao();
			
			StringBuffer sql = new StringBuffer();
			sql.append("update damazzy.receita set bolexcluida = ? where idreceita = ?");
			
			ps = conn.prepareStatement(sql.toString());
			
			ps.setBoolean(cont++, objeto.getBolExcluida());
			ps.setLong(cont++, objeto.getIdReceita());
			
			ps.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao inativar a receita.");
		} finally {
			Conexao.fecharConexao(conn);
		}
	}

	public void excluir(Serializable chave) throws Exception {
		
		/*
		 * Uma receita não pode ser excluída. Somente inativada. 
		 */
		throw new Exception("Não foi possível excluir uma receita. Só é possível inativá-la.");
	}

	public Receita incluir(Receita objeto) throws Exception {

		Connection conn = null;
		
		try {
			
			conn = Conexao.criarConexao();
			
			// Chama o outro incluir.
			incluir(conn, objeto);
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			Conexao.fecharConexao(conn);
		}
		
		return null;
	}
	
	public void incluir(Connection conn, Receita objeto) throws Exception {
		
		StringBuffer sql = new StringBuffer();
		PreparedStatement ps = null;
		int cont = 1;
		
		try {
			
			if (conn != null) {
				sql.append("insert into damazzy.receita (idvenda, datavencimento, datarecebimento, valorpago, ");
				sql.append("valorreceita, bolexcluida, receitarecebida) values (?, ?, ?, ?, ?, ?, ?)");
				
				ps = conn.prepareStatement(sql.toString());
				
				ps.setLong(cont++, objeto.getVenda().getIdVenda());
				ps.setDate(cont++, new java.sql.Date(objeto.getDataVencimento().getTime()));
				
				if (objeto.getDataRecebimento() != null) {
					ps.setDate(cont++, new java.sql.Date(objeto.getDataRecebimento().getTime()));
				} else {
					ps.setNull(cont++, Types.DATE);
				}
				
				ps.setBigDecimal(cont++, objeto.getValorPago());
				ps.setBigDecimal(cont++, objeto.getValorReceita());
				ps.setBoolean(cont++, Boolean.FALSE);
				ps.setInt(cont++, objeto.getReceitaRecebida());
				
				ps.executeUpdate();
				
			} else {
				throw new Exception("Erro. A conexão com o banco de dados não foi estabelecida.");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao incluir a receita.");
		}
	}	

	public List<Receita> listar() throws Exception {
		return this.pesquisar(new Receita());
	}

	public Receita obter(Serializable chave) throws Exception {
		
		Receita receita = null;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		try {
			conn = Conexao.criarConexao();
			
			StringBuffer sql = new StringBuffer();
			sql.append("select * from damazzy.receita where idreceita = ?");
			
			ps = conn.prepareStatement(sql.toString());
			
			Long id = (Long) chave;
			ps.setLong(1, id);
			
			rs = ps.executeQuery();
			
			if (rs.next()) {
				receita = new Receita();
				
				receita.setIdReceita(rs.getLong("idreceita"));
				
				Venda venda = new Venda();
				venda.setIdVenda(rs.getLong("idvenda"));
				receita.setVenda(venda);
				
				receita.setDataVencimento(rs.getDate("datavencimento"));
				receita.setDataRecebimento(rs.getDate("datarecebimento"));
				receita.setValorPago(rs.getBigDecimal("valorpago"));
				receita.setValorReceita(rs.getBigDecimal("valorreceita"));
				receita.setBolExcluida(rs.getBoolean("bolexcluida"));
				receita.setReceitaRecebida(rs.getInt("receitarecebida"));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao obter a receita.");
		} finally {
			Conexao.fecharConexao(conn);
		}
		
		return receita;
	}

	public List<Receita> pesquisar(Receita objeto) throws Exception {
		
		Receita receitaFiltro = objeto;
		Receita receita;
		Venda venda = null;
		Pessoa p = null;
		TipoPagamento tp = null;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<Receita> receitas = new ArrayList<Receita>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		try {
			conn = Conexao.criarConexao();
			
			StringBuffer sql = new StringBuffer();
			sql.append("select r.*, v.idvenda, v.datahora, v.desconto, v.valortotal, v.valortotaldesconto, v.qtdparcelas, ");
			sql.append("p.nome, tp.desctipopagamento from damazzy.receita r ");
			sql.append("inner join damazzy.venda v on v.idvenda = r.idvenda ");
			sql.append("inner join damazzy.pessoa p on v.idpessoacomprador = p.idpessoa ");
			sql.append("inner join damazzy.tipopagamento tp on v.idtipopagamento = tp.idtipopagamento ");
			sql.append("where 1 = 1 ");
			
			if (receitaFiltro.getVenda() != null) {
				sql.append(" and r.idvenda = " + receitaFiltro.getVenda().getIdVenda());
			}
			
			if (receitaFiltro.getDataVencimento() != null) {
				sql.append(" and r.datavencimento = '" + sdf.format(receitaFiltro.getDataVencimento()) + "'");
			}
			
			if (receitaFiltro.getDataRecebimento() != null) {
				sql.append(" and r.datarecebimento = '" + sdf.format(receitaFiltro.getDataRecebimento()) + "'");
			}
			
			if (receitaFiltro.getValorPago() != null) {
				sql.append(" and r.valorpago = " + receitaFiltro.getValorPago());
			}
			
			if (receitaFiltro.getValorReceita() != null) {
				sql.append(" and r.valorreceita = " + receitaFiltro.getValorReceita());
			}
			
			if (receitaFiltro.getBolExcluida() != null) {
				sql.append("and r.bolexcluida = " + receitaFiltro.getBolExcluida());
			}
			
			if (receitaFiltro.getReceitaRecebida() != null) {
				sql.append(" and r.receitarecebida = " + receitaFiltro.getReceitaRecebida());
			}
			
			sql.append(" order by r.idreceita desc");
			
			ps = conn.prepareStatement(sql.toString());
			rs = ps.executeQuery();
			
			while (rs.next()) {
				receita = new Receita();
				receita.setIdReceita(rs.getLong("idreceita"));
				
				venda = new Venda();
				p = new Pessoa();
				
				venda.setIdVenda(rs.getLong("idvenda"));
				
				p.setNome(rs.getString("nome"));
				venda.setPessoaComprador(p);
				venda.setDataHora(rs.getTimestamp("datahora"));
				
				tp = new TipoPagamento();
				tp.setDescTipoPagamento(rs.getString("desctipopagamento"));
				venda.setTipoPagamento(tp);
				
				venda.setDesconto(rs.getInt("desconto"));
				venda.setValorTotal(rs.getBigDecimal("valortotal"));
				venda.setValorTotalDesconto(rs.getBigDecimal("valortotaldesconto"));
				venda.setQtdParcelas(rs.getInt("qtdparcelas"));
				
				receita.setVenda(venda);
				
				receita.setDataVencimento(rs.getDate("datavencimento"));
				receita.setDataRecebimento(rs.getDate("datarecebimento"));
				receita.setValorPago(rs.getBigDecimal("valorpago"));
				receita.setValorReceita(rs.getBigDecimal("valorreceita"));
				receita.setBolExcluida(rs.getBoolean("bolexcluida"));
				receita.setReceitaRecebida(rs.getInt("receitarecebida"));
				
				receitas.add(receita);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao pesquisar a(s) receita(s).");
		} finally {
			Conexao.fecharConexao(conn);
		}
		
		return receitas;
	}

	public void inativarPorIdVenda(Connection conn, Long idVenda) throws Exception {
		
		try {
			
			if (conn != null) {
				
				PreparedStatement ps = null;
				StringBuffer sql = new StringBuffer();
				int cont = 1;
				
				sql.append("update damazzy.receita set bolexcluida = ? where idvenda = ?");
				
				ps = conn.prepareStatement(sql.toString());
				ps.setBoolean(cont++, Boolean.TRUE);
				ps.setLong(cont++, idVenda);
				ps.executeUpdate();
				
			} else {
				throw new Exception("Erro. A conexão com o banco de dados não foi estabelecida.");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Erro ao inativar a(s) receita(s) pelo idVenda: " + idVenda);
		}
	}
}
